package factory.one.service;

import factory.one.entity.*;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

@Service
public class CountService {

    private final OrderService orderService;
    private final BatchService batchService;
    private final RefundService refundService;
    private final MoneyService moneyService;
    private final DeliverService deliverService;
    private final DeliverItemService deliverItemService;

    public CountService(OrderService orderService,
                        BatchService batchService,
                        RefundService refundService,
                        MoneyService moneyService,
                        DeliverService deliverService,
                        DeliverItemService deliverItemService) {
        this.orderService = orderService;
        this.batchService = batchService;
        this.refundService = refundService;
        this.moneyService = moneyService;
        this.deliverService = deliverService;
        this.deliverItemService = deliverItemService;
    }

    private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
    private final int DELAY = 3;

    //统计发送数量 获取所有发送记录 按批次总计
    public void forDeliver(Long orderId){
        executor.schedule(()->{
            Map<Long, AtomicInteger> batchSendMap = new HashMap<>();

            List<Deliver> deliverList = deliverService.listHaveSent(orderId);
            for (Deliver deliver : deliverList){
                List<DeliverItem> itemList = deliverItemService.listByDeliver(deliver.getId());
                for (DeliverItem item : itemList){
                    if (!batchSendMap.containsKey(item.getBatchId())){
                        batchSendMap.put(item.getBatchId(),new AtomicInteger(0));
                    }
                    batchSendMap.get(item.getBatchId()).addAndGet(item.getNumber());
                }
            }

            int sendSum = 0;
            List<Batch> batchList = batchService.list(orderId);
            for (Batch b : batchList) {
                if (batchSendMap.containsKey(b.getId())) {
                    b.setSendNum(batchSendMap.get(b.getId()).intValue());
                }
                sendSum += b.getSendNum();
                batchService.updateSendAndRefund(b.getId(), b.getSendNum(), b.getRefundNum());
            }

            //订单
            orderService.updateSendNumber(orderId, sendSum);
        },DELAY,TimeUnit.SECONDS);
    }

    public void submit(Long orderId) {
        executor.schedule(() -> {
            //统计退货数量
            List<Refund> refundList = refundService.listByOrder(orderId);
            Map<Long, AtomicInteger> batchRefundMap = new HashMap<>();
            for (Refund r : refundList) {
                if (!batchRefundMap.containsKey(r.getBatchId())) {
                    batchRefundMap.put(r.getBatchId(), new AtomicInteger(0));
                }
                batchRefundMap.get(r.getBatchId()).addAndGet(r.getNumber());
            }

            //统计批次更新 获取所有批次 更新发送 再总计
            int produceSum = 0;
            int sendSum = 0;
            int refundSum = 0;
            List<Batch> batchList = batchService.list(orderId);
            for (Batch b : batchList) {
                if (batchRefundMap.containsKey(b.getId())){
                    b.setRefundNum(batchRefundMap.get(b.getId()).intValue());
                }
                produceSum += b.getProduceNum();
                sendSum += b.getSendNum();
                refundSum += b.getRefundNum();
                batchService.updateSendAndRefund(b.getId(), b.getSendNum(), b.getRefundNum());
            }

            //订单
            orderService.updateNumber(orderId, produceSum, sendSum, refundSum);
        }, DELAY, TimeUnit.SECONDS);
    }

    public void submitForAmount(Long orderId) {
        executor.schedule(() -> {
            //统计收支
            List<Money> moneyList = moneyService.listByOrder(orderId);
            long actualAmount = 0;
            for (Money m : moneyList) {
                switch (m.getType()) {
                    case 1:
                        actualAmount += m.getAmount();
                        break;
                    case 2:
                        actualAmount -= m.getAmount();
                        break;
                }
            }

            //订单
            orderService.updateAmount(orderId, actualAmount);
        }, DELAY, TimeUnit.SECONDS);
    }

}
